package com.mzplayer.videoview.base;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.SeekBar;

import com.mzplayer.utils.Util;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
/**
 * @Description: 实现了一些基本的UI逻辑
 *               继承本类只需要实现定义的抽象方法即可
 *               参考EasyVideoView
 * @Author: 麦子
 * @QQ: 3332174009
 * @CreateDate: 2021/6/27
 */
public abstract class EasyParent extends StandardParent implements SeekBar.OnSeekBarChangeListener, View.OnClickListener {
    private final LoadingEvent loadingEvent = new LoadingEvent();
    private final PlayEvent playEvent = new PlayEvent();
    private int duration;
    private int startPosition;
    private boolean fromSeekBar;
    private boolean isSeeking;

    public EasyParent(Context context) {
        this(context, null);
    }

    public EasyParent(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public EasyParent(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initResource(context);
        inflate(context, getLayoutID(), this);
        setBackgroundColor(getBackgroundColor());
        initViews();
        initListener();
        hide();
    }

    /**
     * 初始化一些特殊的资源,没有的化可以空实现
     * @param context
     */
    protected abstract void initResource(Context context);

    protected abstract int getLayoutID();

    protected abstract void initViews();

    protected abstract void initListener();

    protected abstract void lock();

    protected abstract void unlock();

    protected abstract void setTitle(String title);

    protected abstract void showError(StringBuilder err);

    protected abstract void hideError();

    protected abstract void showSeekBar();

    protected abstract void hideSeekBar();

    protected abstract void onPlayTimeFlush(boolean isLive,String currentTime, String maxTime);

    protected abstract void onSystemTimeFlush(String format);

    protected abstract void setSeekBarMax(int max);

    protected abstract void setSeekBarProgress(int progress);

    protected abstract void setSeekBarSecondaryProgress(int secondaryProgress);

    protected abstract void showLoading(String flag);

    protected abstract void hideLoading();

    protected abstract void onLoadingFlush();

    protected abstract void showBright(int position, int max);

    protected abstract void hideBright();

    protected abstract void onBrightFlush(int position);

    protected abstract void showVolume(int position, int max);

    protected abstract void hideVolume();

    protected abstract void onVolumeFlush(int position);

    protected abstract void showSeek(String currentTime, String maxTime);

    protected abstract void hideSeek();

    protected abstract void onSeekFlush(boolean toEnd, String currentTime, String maxTime);

    @Override
    public void show(int delay) {
        super.show(delay);
        removeCallbacks(playEvent);
        post(playEvent);
    }

    @Override
    protected void onPreparing() {
        hideError();
        showLoading("正在加载 ... ");
        duration = 0;
        setTitle(getMediaData().getName());
        setSeekBarProgress(0);
        setSeekBarSecondaryProgress(0);
        setSeekBarMax(100);
        showSeekBar();
        onPlayTimeFlush(false,"00:00", "00:00");
    }

    @Override
    protected void onPrepared() {
        hideLoading();
        String currentTime = Util.stringForTime(getCurrentPosition());
        duration = (int) getDuration();
        if (duration == 0) {
            hideSeekBar();
            onPlayTimeFlush(true,currentTime, "");
        } else {
            setSeekBarMax(duration);
            onPlayTimeFlush(false,currentTime, Util.stringForTime(duration));
        }
        show(defaultDelay);
        start();
    }

    @Override
    protected void onError(int what, int extra) {
        hideLoading();
        showError(new StringBuilder("播放出错(").append(what).append(",").append(extra).append(")"));
    }

    @Override
    protected void onBufferingUpdate(int position) {
        setSeekBarSecondaryProgress(position);
    }


    @Override
    protected void onTouchTrackingStart(int type, int position, int max) {
        if (type == TYPE_SEEK) {
            startPosition = position;
            showSeek(Util.stringForTime(position), Util.stringForTime(max));
            show(0);
            isSeeking = true;
        } else if (type == TYPE_BRIGHT) {
            showBright(position, max);
        } else if (type == TYPE_VOLUME) {
            showVolume(position, max);
        }
    }

    @Override
    protected void onTouchTrackingMove(int type, int position, int max) {
        if (type == TYPE_SEEK) {
            onSeekFlush(position >= startPosition, Util.stringForTime(position), Util.stringForTime(max));
            if (!fromSeekBar) {
                setSeekBarProgress(position);
            }
        } else if (type == TYPE_BRIGHT) {
            onBrightFlush(position);
        } else if (type == TYPE_VOLUME) {
            onVolumeFlush(position);
        }
    }

    @Override
    protected void onTouchTrackingStop(int type, int position, int max) {
        if (type == TYPE_SEEK) {
            hideSeek();
            if (duration != 0) {
                seekTo(position);
            }
            isSeeking = false;
            show(defaultDelay);
        } else if (type == TYPE_BRIGHT) {
            hideBright();
        } else if (type == TYPE_VOLUME) {
            hideVolume();
        }
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (fromUser) {
            onTouchTrackingMove(TYPE_SEEK, progress, seekBar.getMax());
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        fromSeekBar = true;
        onTouchTrackingStart(TYPE_SEEK, seekBar.getProgress(), seekBar.getMax());
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        onTouchTrackingStop(TYPE_SEEK, seekBar.getProgress(), seekBar.getMax());
        fromSeekBar = false;
    }

    @Override
    protected void onLoadingStart() {
        showLoading("正在缓冲 ... ");
        removeCallbacks(loadingEvent);
        post(loadingEvent);
    }

    @Override
    protected void onLoadingEnd() {
        removeCallbacks(loadingEvent);
        hideLoading();
    }

    class LoadingEvent implements Runnable {

        @Override
        public void run() {
            onLoadingFlush();
            postDelayed(this, 500);
        }
    }

    class PlayEvent implements Runnable {

        @Override
        public void run() {
            String format = new SimpleDateFormat("HH:mm", Locale.CHINA).format(new Date());
            onSystemTimeFlush(format);
            int currentPosition = (int) getCurrentPosition();
            String currentTime = Util.stringForTime(currentPosition);
            if (duration != 0) {
                onPlayTimeFlush(false,currentTime, Util.stringForTime(duration));
                if (!isSeeking) {
                    setSeekBarProgress(currentPosition);
                }
            } else if(currentPosition>0){
                onPlayTimeFlush(true,currentTime, "");
            }
            if (isShowing()) {
                postDelayed(this, 500);
            }
        }
    }
}
